<?php
/**
 * SimplifyPHP Framework
 *
 * This file is part of SimplifyPHP Framework.
 *
 * SimplifyPHP Framework is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * SimplifyPHP Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Rodrigo Rutkoski Rodrigues, <rutkoski@gmail.com>
 */

require_once (SY_DIR . '/lib/outlet/Outlet.php');

/**
 * Data Access Object for OutletORM
 * 
 * @author Rodrigo Rutkoski Rodrigues <rutkoski@gmail.com>
 * @package Simplify_Kernel_DAO
 */
class OutletDAO extends Outlet
{

  /**
   * 
   * @var array
   */
  protected static $classes = array();
  
  public function loadYaml($file)
  {
    if (! sy_path_is_absolute($file)) {
      $file = Simplify::getConfig()->get('app_dir').'/model/'.$file;
    }
    
    $tables = spyc_load_file($file);
    
    $this->config($tables);
  }

  /**
   * 
   * @return OutletDAO
   */
  public static function getInstance()
  {
    if (empty(self::$instance)) {
      self::$instance = new self();
    }
    
    return self::$instance;
  }

  public function __construct()
  {
    parent::__construct(self::_getConfig());
    
    $this->createProxies();
  }

  /**
   * 
   * @param $name
   * @param $callInit
   * @return Outlet
   */
  public function addEntity($name, $callInit = true)
  {
    $names = ( array ) $name;
    
    foreach ($names as $name) {
      $entity = new $name();
      
      self::$classes[$entity->getName()] = array(
        'table' => $entity->getTable(), 'props' => $entity->getFields(), 'associations' => $entity->getAssociations() 
      );
    }
    
    if ($callInit)
      $this->_init();
    
    return $this;
  }
  
  public function config(array $entities)
  {
    foreach ($entities as $clazz=>$entity) {
      $this->addClass($clazz, $entity, false);
    }
    
    $this->_init();
  }

  protected function _init()
  {
    //$this->config = new OutletConfig($this->_getConfig());
    //$this->mapper = new OutletMapper($this->config);
    parent::__construct(self::_getConfig());
    $this->createProxies();
  }

  /**
   * 
   * @param $name
   * @param $callInit
   * @return unknown_type
   */
  public function addClass($class, $params = array(), $callInit = true)
  {
    if (!class_exists($class)) {
      $clazz = "class $class extends Entity {}";
      eval($clazz);
    }
    
    if (empty($params['table'])) $params['table'] = Inflector::tableize(strtolower($class));
    
    self::$classes[$class] = $params;
    
    if ($callInit) $this->_init();
    
    return $this;
  }

  /**
   * 
   * @return unknown_type
   */
  protected function _getConfig()
  {
    $config = array(
      
      'connection' => array(
        
        'dsn' => Simplify::getConfig()->get('{env}:database:type') . ':host=' . Simplify::getConfig()->get('{env}:database:host') . ';dbname=' . Simplify::getConfig()->get(
            '{env}:database:name'), 'username' => Simplify::getConfig()->get('{env}:database:username'), 
        'password' => Simplify::getConfig()->get('{env}:database:password'), 'dialect' => Simplify::getConfig()->get('{env}:database:type') 
      ), 'classes' => self::$classes 
    );
    
    return $config;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/lib/outlet/Outlet#from($from)
   */
  public function from($from)
  {
    if (! class_exists($from . '_OutletProxy')) {
      $this->addEntity($from);
    }
    
    return parent::from($from);
  }

  /**
   * (non-PHPdoc)
   * @see simplify/lib/outlet/Outlet#load($cls, $pk)
   */
  public function load($cls, $pk)
  {
    if (! class_exists($cls . '_OutletProxy')) {
      $this->addEntity($cls);
    }
    return parent::load($cls, $pk);
  }

  /**
   * (non-PHPdoc)
   * @see simplify/lib/outlet/Outlet#select($clazz, $query, $params)
   */
  public function select($clazz, $query = '', $params = array())
  {
    if (! class_exists($clazz . '_OutletProxy')) {
      $this->addEntity($clazz);
    }
    return parent::select($clazz, $query, $params);
  }

  public function query($query = '', array $params = array())
  {
    $stmt = parent::query($query, $params);
    
    OutletLog::log($stmt);
    
    return $stmt;
  }

}

?>